package com.imooc.security;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
import org.springframework.security.web.access.ExceptionTranslationFilter;
import org.springframework.security.web.context.SecurityContextPersistenceFilter;

/**
 * @author wangyouliang
 */
@Configuration
@EnableResourceServer
public class GatewaySecurityConfig extends ResourceServerConfigurerAdapter {

    @Autowired
    private GatewayWebSecurityExpressionHandler gatewayWebSecurityExpressionHandler;

    @Autowired
    private GatewayAccessDeniedHandler accessDeniedHandler;

    @Autowired
    private GatewayAuthenticationEntryPoint authenticationEntryPoint;

    /**
     * 如果想追求更高的安全性，可以通过 resourceId 去控制令牌可以访问哪些资源服务器。
     */
//    @Override
//    public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
//        resources.resourceId("gateway");
//    }

    @Override
    public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
        resources
                .authenticationEntryPoint(authenticationEntryPoint) // 针对401的处理
                .accessDeniedHandler(accessDeniedHandler) // 针对403的处理
                .expressionHandler(gatewayWebSecurityExpressionHandler);
    }

    @Override
	public void configure(HttpSecurity http) throws Exception {
		http
            .addFilterBefore(new GatewayRateLimitFilter(), SecurityContextPersistenceFilter.class) // SecurityContextPersistenceFilter是spring过滤器链中的第一个过滤器。
            .addFilterBefore(new GatewayAuditLogFilter(), ExceptionTranslationFilter.class)
            .authorizeRequests()
			.antMatchers("/token/**").permitAll()
            .anyRequest().access("#permissionService.hasPermission(request, authentication)");
	}
	
}
